#ifndef __FUNC_SERVICE_H__
#define __FUNC_SERVICE_H__

//#include"FuncService.hpp"
#include<functional>
#include"../Base/Network/WsService.hpp"
#include"../Base/Tools/ObjectPool.hpp"
#include"../Base/Network/NetworkDef.hpp"
#include"../Base/Network/Session.hpp"
#include"../Base/Serialize/SerialBuffer.hpp"
#include"../Base/Serialize/SerialVector.hpp"
#include"../Base/Serialize/SerialMap.hpp"
#include"App.h"

namespace SC_SUN
{


class FuncService
{

public:
    using Callback = std::function<void(uWS::WebSocket<false,true,void*>* ws, MMFNetwork::MMFMessageHeader* pkg)>;

protected:

    MMF::WsService<void*> mService; 
    Callback mOpenHandler;
    Callback mCloseHandler;
    MMF::ObjectPool<std::vector<char>> mSerialInPool;

    

public:

    FuncService(const std::string& router, uint16_t port);
    ~FuncService();

    void RegisterClientOpenHanlder(const Callback&& handler);
    void RegisterClientCloseHanlder(const Callback&& handler);
    std::vector<char>& GetSerialInBuffer() {return mSerialInPool.GetObject();}

    bool Start();
    void Stop();

    MMF::WsDispather<void*>& Dispathter();

    //推送广播消息
    template<typename T>
    void BroadcastMessage(const char* msgName, T msg)
    {
        using namespace MMFNetwork;
        using namespace MMFSerialize;

        uint32_t headLen = CalcMessageHeadLen(msgName);
        std::vector<char>& iBuff = GetSerialInBuffer();
        MMFSerialize::SerialInBuffer iSBuff(iBuff.data() + headLen, (uint32_t)iBuff.size() - headLen);
        iSBuff >> msg;
        uint32_t total = FillMessageHead(iBuff, headLen, msgName, iSBuff.mPos);

        const std::unordered_set<uWS::WebSocket<false,true,void*>*>& wsSockets = mService.Dispathter().Session();
        for (const auto& val : wsSockets)
        {
            val->send(std::string_view(iBuff.data(), total), uWS::OpCode::BINARY, false);
        }
    }

    template<typename T>
    void SendMsgTo(uWS::WebSocket<false,true,void*>* ws, const char* msgName, T msg)
    {
        using namespace MMFNetwork;
        using namespace MMFSerialize;

        uint32_t headLen = CalcMessageHeadLen(msgName);
        std::vector<char>& iBuff = GetSerialInBuffer();
        MMFSerialize::SerialInBuffer iSBuff(iBuff.data() + headLen, (uint32_t)iBuff.size() - headLen);
        iSBuff >> msg;
        uint32_t total = FillMessageHead(iBuff, headLen, msgName, iSBuff.mPos);
        ws->send(std::string_view(iBuff.data(), total), uWS::OpCode::BINARY, false);
    }
};

}

#endif
